using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using DbHelp = Widgetsphere.Core.DataAccess.DatabaseHelper;
using System.Data.Common;
using System.Text.RegularExpressions;
using Widgetsphere.Core.Logging;


namespace Widgetsphere.Core.DataAccess
{
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  public abstract partial class DomainCollectionBase : DataTable, IDomainCollection
  {
    protected string ConnectionString
    {
      get
      {
        SubDomainBase sdBase = (SubDomainBase)this.DataSet;
        return sdBase.ConnectionString;
      }
    }

    int IDomainCollection.Count
    {
      get { return this.Rows.Count; }
    }

    public void RunSelectCommand(SelectCommand rule)
    {
      IDbCommand fillCommand = PersistableDomainCollectionBase.GetFillCommand(rule.ConnectionString, rule.StoredProcedureName);
      foreach (string paramKey in rule.ParameterValues.Keys)
      {
        PersistableDomainCollectionBase.SetParameterValue(fillCommand, paramKey, rule.ParameterValues[paramKey]);
      }

      if (rule.TimeOut > 0)
        fillCommand.CommandTimeout = rule.TimeOut;

      this.FillDataTable(rule.ConnectionString, fillCommand);
    }

    public static IDbCommand GetFillCommand(string connectionString, string spName)
    {

      StoredProcedure sp = StoredProcedureFactory.GetStoredProcedure(connectionString, spName);
      return sp.GetDataSetCommand();
    }

    public void FillDataTable(string connectionString, IDbCommand selectCommand)
    {
      try
      {
        IDbDataAdapter da = DbHelp.GetDataAdapter();
        SetTableMappings(ref da);
        da.SelectCommand = selectCommand;
        DbHelp.SetConnections(da, DbHelp.GetConnection(connectionString));
        DbHelp.Fill(da, this);
      }
      catch (Exception ex)
      {
			MessageLog.LogError(LogClass.WSCommonDataAccess, ex);
        DataRow[] drErrors = this.GetErrors();
        if (drErrors.Length > 0)
        {
          System.Diagnostics.Debug.WriteLine(String.Format("Error In Table: {0}", this.TableName));
        }
        foreach (System.Data.DataRow dr in drErrors)
        {
          foreach (System.Data.DataColumn dc in dr.GetColumnsInError())
          {
            System.Diagnostics.Debug.WriteLine(String.Format("Column: {0} - Error : {1}", dc.ColumnName, dr.GetColumnError(dc)));
          }
        }
        throw;
      }
    }

    protected void SetTableMappings(ref IDbDataAdapter da)
    {
      DataTableMapping tableMap = new DataTableMapping("Table", this.TableName);
			foreach (DataColumn dc in this.Columns)
      {
        tableMap.ColumnMappings.Add(DataColumnNameToParameterName(dc.ColumnName), dc.ColumnName);
      }
      da.TableMappings.Add(tableMap);
    }

    protected static string DataColumnNameToParameterName(string dataColumnName)
    {
      Regex digitregex = new Regex("(?<caps>[A-Z,_])");
      string parameterName = digitregex.Replace(dataColumnName, "_$+");
      parameterName = parameterName.ToLower().TrimStart('_');
      return parameterName;
    }

    public bool IsColumnInPrimaryKey(DataColumn dataColumn)
    {
      foreach (DataColumn dc in this.PrimaryKey)
      {
        if (dataColumn == dc)
          return true;
      }
      return false;
    }



  }
}
